package com.hjy.service;

import com.hjy.dao.EmployeeDao;
import com.hjy.modle.Employee;
import org.apache.dubbo.config.annotation.DubboService;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.concurrent.TimeUnit;

/**
 * @author jinyuhe
 * @date 2022/07/14
 */
@DubboService
@Component
@Service
public class EmployeeServiceImpl implements EmployeeService {

    @Autowired
    private EmployeeDao dao;
    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    //插入操作会秦孔realTimeCache 缓存
    @CacheEvict(value = "realTimeCache", allEntries = true)
    //指定发送异常回滚
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void addEmployee(Employee employee) {
        this.dao.insertEmployee(employee);
    }

    //插入操作会秦孔realTimeCache 缓存
    @CacheEvict(value = "realTimeCache", key = "'employee_'+#id")
    @Override
    public Employee findEmployeeById(int id) {
        return this.dao.selectEmployeeById(id);
    }

    //使用双重检查锁解决热点缓存问题
    @Override
    public Integer findEmployeeCount() {
        BoundValueOperations<Object, Object> ops = this.redisTemplate.boundValueOps("count");
        Object count = ops.get();
        if (count == null) {
            synchronized (this) {
                count = ops.get();
                if (count == null) {
                    //从db 中查
                    System.out.println("count:");
                    count = this.dao.selectEmployeeCount();
                    //写入到redis 中 10 秒缓存
                    ops.set(count, 10, TimeUnit.SECONDS);
                }
            }
        }
        return (Integer) count;
    }
}
